home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 25
/
CU Amiga Magazine's Super CD-ROM 25 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-08].iso
/
CUCD
/
Programming
/
PPCpack
/
libs.txt
< prev
next >
Wrap
Text File
|
1998-04-16
|
8KB
|
333 lines
E) PPC Shared Libraries
=======================
This article handles:
1) Using PPC Shared Libraries
2) Creating PPC Shared Libraries
It assumes you already read c.txt and mixed.txt.
1) Using PPC Shared Libraries
-----------------------------
Well, basically it is the same like using a 68k Shared Libraries.
Internally WarpOS Shared Libraries have exactly the same format
like 68k Shared Libraries. Only that some entries on the jumptable
point to PPC Code. Basically they are all Mixed Binary. At least
the Library-Init and -Expunge are done in 68k.
There are three types of PPC Shared Libraries:
A) 68k/PPC Mixed-Libs
B) 68k/PPC Mixed-Fat-Libs
C) PPC-Only Libs
An 68k/PPC Mixed-Lib is a library that has every of it's functions
available for both 68k. Some (or all) of the functions are also available
as special PPC Versions. The PPC-Versions have different offsets than the
68k-Versions. Only a PPC-System can use the PPC-Functions, but the library
can also be used on a 68k System, if only the 68k functions are used.
rtgmaster.library is an example of Type A).
+ no Contextswitches needed
+ only one Lib for both 68k and PPC functions
- to compile 68k+PPC Versions of a program constructs like
#ifdef __PPC__
CopyRtgBlitPPC(...);
#else
CopyRtgBlit(...);
#endif
have to be used.
A 68k/PPC Mixed-Fat-Lib implements every function only once. All functions
use a 68k Header. This header finds out, if a PPC is present. If yes,
it uses the PPC-optimized version, else the 68k version.
+ only one Lib for both 68k and PPC functions
+ no complicated constructs needed
- Every function uses two Contextswitches (one from PPC to 68k to
run the header, one from 68k to PPC to run the optimized function).
This type should only be used (if used at all !!!) for functions that
take VERY long (for a MPEG Lib or such...)
PPC-Only Libs run only on PPC-Systems. There might exist an 68k version
of the library with a different name.
+ no complicated constructs needed
+ no Contextswitches needed
- two libraries, one for PPC, one for 68k
To use a PPC Library you would do:
- include the clib-include-file
- Call the function
For libraries not included in ppcamiga.lib (all OS Libs and rtgmaster
are included there) you have additionally to create a PPC-Stub-File,
like described in c.txt, and link together with this. You only need
the PPC-Stub-File for 68k functions in the Library (if it is a
PPC-Only-Lib you do not need it). You don't include any pragmas.
That is ALL about this theme.
2) Creating PPC-Shared-Libraries
Principially you have to do like described in mixed.txt, creating a Mixed
Binary (Even a PPC-Only Lib is a mixed Binary, as the Library Init is always 68k).
You specify the Library-Init like this:
void INIT_0_InitTheLib(register __a6 struct MyLibBase *base)
{
MyLibBase=base;
// Rest of the Init
}
You specify the Library-Expunge like:
void EXIT_0_ExitTheLib(register __a6 struct MyLibBase *base)
{
base=MyLibBase;
}
The structure MyLibBase has to be defined before, of course. After the includes
you have to specify:
struct MyLibBase
{
struct Library mlb_MyLibBase;
// Rest of data you want to store
};
struct MyLibBase *MyLibBase;
#pragma libbase MyLibBase
If you want your library also to work on a plain 68k system, you add:
struct Library *PowerPCBase;
void INIT_0_PowerPCBase(void)
{
PowerPCBase=OpenLibrary("powerpc.library",7);
}
void EXIT_0_PowerPCBase(void)
{
if (PowerPCBase) CloseLibrary(PowerPCBase);
}
Now you can check the variable PowerPCBase in your functions to find out, if
this is a PPC or a 68k system. (if the variable is 0, it is a 68k System).
Note: If you would open powerpc.library inside the Libinit of your library,
your library would fail to open if powerpc.library fails to open. Because of
this, we had to do it in the init of powerpc.library itselves...
Take this also a general rule: if stuff in the LibInit fails to open => the
library fails to open.
Principially the rest of the Library is just defining the Library functions, but
i will explain it a bit more detailed:
You have to define the following files:
MyLib_protos.h
MyLib_lib.fd
MyLib.c
MyLib_PPC.c
All works after the rules for Mixed Binaries.
- MyLib.c contains the LibInit and the 68k functions of your library (if it has any).
- MyLib_PPC.c contains the PPC functions of your library
- MyLib_lib.fd contains the FD Stuff for the library
- MyLib_protos.h contains the Prototypes for the library
MyLib_protos.h
--------------
A Proto-File for a PPC Shared library looks like (Example) :
#ifndef MYLIB_PROTOS_H
#define MYLIB_PROTOS_H
#ifndef __PPC__
#ifdef __cplusplus
extern "C" {
#endif
void test68k(int bla);
int foo68k(int bar);
#ifdef __cplusplus
};
#endif
#else
extern "AmigaLib" MyLibBase
{
// The numbers are the function offsets in the jumptable !!!
void testPPC_(struct Library *,int)=-42;
int fooPPC_(struct Library *,int)=-48;
}
__inline void testPPC(int bla)
{
extern struct Library *MyLibBase;
testPPC_(MyLibBase,bla);
}
__inline int fooPPC(int bar)
{
extern struct Library *MyLibBase;
return fooPPC_(MyLibBase,bar);
}
#endif
#endif
Note, that you have to create a PPC-Stub, like explained in c.txt, if you
want to use the 68k functions inside a PPC Source (inside a 68k source
this is not needed, of course).
MyLib_lib.fd:
-------------
FDs for PPC Shared Libraries are defined exactly like FDs for 68k-Libraries.
The only difference is, that NO PARAMETERS ARE GIVEN FOR PPC FUNCTIONS, EVEN
IF THEY HAVE SOME.
Example (no complete FD File, only two example lines of a FD File...)
; ...
testfunc68k(bla)(d0)
testfuncPPC()()
; ...
Both functions have one parameter, but the parameter of the PPC Function is not
specified in the FD-File.
MyLib.c
-------
Example:
#include <clib/exec_protos.h>
#include <pragma/exec_lib.h>
#include <exec/libraries.h>
struct MyLibBase
{
struct Library mlb_MyLibBase;
// Rest of data you want to store
};
struct MyLibBase *MyLibBase;
#pragma libbase MyLibBase
void INIT_0_InitTheLib(register __a6 struct MyLibBase *base)
{
MyLibBase=base;
// Rest of the Init
}
You specify the Library-Expunge like:
void EXIT_0_ExitTheLib(register __a6 struct MyLibBase *base)
{
base=MyLibBase;
}
If you want your library also to work on a plain 68k system, you add:
struct Library *PowerPCBase;
void INIT_0_PowerPCBase(void)
{
PowerPCBase=OpenLibrary("powerpc.library",7);
}
void EXIT_0_PowerPCBase(void)
{
if (PowerPCBase) CloseLibrary(PowerPCBase);
}
void test68k(register __d0 int bla)
{
}
int foo68k(register __d0 int bar)
{
return 0;
}
MyLib_PPC.c
-----------
The most important additional thing to usual Mixed Binary Sources is, that all
Library functions have to be specified with __saveds.
Example:
void __saveds testPPC(int bla)
{
}
int __saveds fooPPC(int bar)
{
return 0;
}
As you see, my example-library is a Type A) Library (PPC-Mixed...). You should now
be able to create Libraries of all three types yourselves.
Note: After you compiled your library, you have to manually remove all PPC-Functions from
the automatically generated MyLib_lib.h. This pragma-File has been generated
from the FD-File, but pragma-Files are only for 68k. If you do not do this, you
will get errors when using the Library.
Possible Problems:
- "I get illegal 24 Bit Relocation all the time"
Possible Reasons for this one:
- you forgot to set "Debuggable Code" for the first Compilation. Please change
the compiler options to Debugging Code and compile once more.
- You tried to call a 68k Assembler Function from the PPC Part. This can only
be done using a manual Context-Swtich. The Automatic Contextswitch only
handles functions written in C.
- you tried to call a function of MyLib.c that is specified with register
parameters. To fix this, simply define (Example):
In PPC Code:
//...
test68k_Stack(bla);
//...
In 68k Code:
void test68k_Stack(int bla)
{
test68k(int bla);
}
void test68k(register __d0 int bla)
{
}
This the automatic Contextswitch can handle. If you do not like this solution,
use the manual Contextswitch or implement the 68k function in PPC Code.